﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Bzure.Common.Events
{
    [Serializable]
    public abstract class EventComponentBase<EventDefine> : IEventComponent<EventDefine> 
    {
        protected Dictionary<object, Delegate> handlers = new Dictionary<object, Delegate>();
        protected Dictionary<object, EventDefine> events = new Dictionary<object, EventDefine>();
        protected object EventHandlerKey
        {
            get { return new object(); }
        }

        public void AddEventHandler(EventDefine eventType, Delegate handler)
        {
            lock (this)
            {
                object handlerKey = EventHandlerKey;
                handlers.Add(handlerKey, handler);
                events.Add(handlerKey, eventType);
            }
        }

        public void RemoveEventHandler(EventDefine eventType, Delegate handler)
        {
            lock (this)
            {
                foreach (object handlerKey in events.Keys)
                {
                    if (events[handlerKey].Equals(eventType))
                    {
                        if ((Delegate)handlers[handlerKey] == handler)
                        {
                            handlers.Remove(handlers[handlerKey]);
                            events.Remove(events[handlerKey]);
                            break;
                        }
                    }
                }
            }
        }

        protected IEnumerable<Delegate> GetEventHandlers(EventDefine eventType)
        {
            List<Delegate> handlerList = new List<Delegate>();
            lock (this)
            {
                foreach (object handlerKey in events.Keys)
                {
                    if (events[handlerKey].Equals(eventType))
                    {
                        handlerList.Add(handlers[handlerKey]);
                    }
                }
            }
            return handlerList;
        }
        public void RaiseEvent(EventDefine eventType, params  object[] parameters)
        {
            foreach (Delegate g in GetEventHandlers(eventType))
            {
                try
                {
                    g.Method.Invoke(g.Target , parameters);
                }
                catch
                {
                }
            }
        }
    }


    [Serializable]
    public abstract class EventComponentBase<EventDefine, Handler> : IEventComponent<EventDefine, Handler>
    {
        protected Dictionary<object, Handler> handlers = new Dictionary<object, Handler>();
        protected Dictionary<object, EventDefine> events = new Dictionary<object, EventDefine>();
        protected object EventHandlerKey
        {
            get { return new object(); }
        }

        public void AddEventHandler(EventDefine eventType, Handler handler)
        {
            lock (this)
            {
                object handlerKey = EventHandlerKey;
                handlers.Add(handlerKey, handler);
                events.Add(handlerKey, eventType);
            }
        }

        public void RemoveEventHandler(EventDefine eventType, Handler handler)
        {
            lock (this)
            {
                foreach (object handlerKey in events.Keys)
                {
                    if (events[handlerKey].Equals(eventType))
                    {
                        if (handlers[handlerKey].Equals (handler))
                        {
                            handlers.Remove(handlers[handlerKey]);
                            events.Remove(events[handlerKey]);
                            break;
                        }
                    }
                }
            }
        }

        protected IEnumerable<Handler> GetEventHandlers(EventDefine eventType)
        {
            List<Handler> handlerList = new List<Handler>();
            lock (this)
            {
                foreach (object handlerKey in events.Keys)
                {
                    if (events[handlerKey].Equals(eventType))
                    {
                        handlerList.Add(handlers[handlerKey]);
                    }
                }
            }
            return handlerList;
        }
        public void RaiseEvent(EventDefine eventType,params  object[] parameters)
        {
            foreach (Handler g in GetEventHandlers(eventType))
            {
                try
                {
                    Delegate gg=g as Delegate ;
                    gg.Method.Invoke(gg.Target , parameters);
                }
                catch
                {
                }
            }
        }
    }
}
